Steve Langasek: bzr-git case study
Robert Collins did a very nice writeup not so long ago of
creating a Debian package with bzr-builddeb,
but he starts from the assumption that upstream also uses bzr. As we all
know, there are many projects that have their upstream sources in a VCS, but
don't use bzr. Can we still get reasonable results from bzr-builddeb,
including the ability to merge new upstream releases direct from the VCS, if,
say, upstream is using git?
Yes, we can!
Of course, if you're happy with using git as the VCS for your Debian packaging
already, there's probably no compelling reason for you to switch to bzr. But
if you prefer to use bzr and have been frustrated at having to choose between
being able to use the VCS client of your choice for your packages and being
able to use your VCS client to access upstream revision history, read on.
Thanks to the fine work of Jelmer Vernooij and friends,
bzr-git
has been
usable for a while if you just want to track the default git branch. But
what if you care about tracking multiple upstream branches?
Enter bzr git-import
, which we'll use to set up a bzr repo from scratch for
our cifs-utils
package, with a full import of all the branches of upstream's
git tree.
First we do some work to set up a shared bzr repository. As long as we're
going to the effort of mirroring all the git branches, we probably want to
publish them for other people to use, so we make sure our bzr repository is
reasonably configured for
sharing data between branches:
$ bzr init-repo --no-trees cifs-utils.server
Shared repository (format: 2a)
Location:
shared repository: cifs-utils.server
$ cd cifs-utils.server
Then we use bzr git-import
, provided by the bzr-git
plugin, to do a full
import of the upstream branches into a cleverly named subdirectory:
$ bzr git-import git://git.samba.org/cifs-utils.git upstream
[/ ] Counting objects: 181, done.
Now we create our own local 'trunk' for the package, by branching from the
upstream tag matching the release version we're going to package.
$ bzr branch -r tag:cifs-utils-4.0rc1 upstream/HEAD trunk
Branched 42 revision(s).
Do a little more prep work for future branches...
$ mkdir branches
And that's it. Now we have a bzr repo locally that we can push out to our
hosting server of choice (N.B.: we could do this all directly on the server,
but alioth doesn't currently have bzr-git
installed):
$ rsync -az . alioth.debian.org:/bzr/pkg-samba/cifs-utils/
$
Now that we have a bzr repository, it's time to get ourselves a working
directory and do some packaging. We're probably going to work with multiple
branches locally as well, so we create another shared repository for local
use, and get a copy of the trunk branch we created before.
$ bzr init-repo cifs-utils
Shared repository with trees (format: 2a)
Location:
shared repository: cifs-utils
$ cd cifs-utils
$ bzr co bzr+ssh://bzr.debian.org/bzr/pkg-samba/cifs-utils/trunk
Now we grab the upstream tarball, and whip up some quick packaging with
(what else?) debhelper 7:
$ wget ftp://ftp.samba.org/pub/samba/cifs-utils/cifs-utils-4.0rc1.tar.bz2
$ ln -s cifs-utils-4.0rc1.tar.bz2 cifs-utils_4.0~rc1.orig.tar.bz2
$ cd trunk
$ mkdir -p debian/source
$ echo '3.0 (quilt)' > debian/source/format
$ echo 7 > debian/compat
$ cp /usr/share/doc/debhelper/examples/rules.tiny debian/rules
$ dch --package cifs-utils --versio 4.0~rc1-1 --create 'Initial package'
Create debian/control by hand, generate an initial source package, and import
it into bzr with bzr-builddeb
.
$ debuild -uc -us -S -i
$ rm -r debian
$ bzr import-dsc ../*.dsc
$
Since we want to continue tracking upstream development, we need to
periodically sync our bzr import of the git tree.
$ bzr git-import git://git.samba.org/cifs-utils.git bzr+ssh://bzr.debian.org/bzr/pkg-samba/cifs-utils/upstream
$
And when we find a new upstream version in that import that we want to
package, bzr-builddeb
makes this a snap, too.
$ cd cifs-utils
$ wget ftp://ftp.samba.org/pub/samba/cifs-utils/cifs-utils-$version.tar.bz2
$ cd trunk
$ bzr merge-upstream --v3 --version $version_with_epoch \
../cifs-utils-$version.tar.bz2 -r tag:cifs-utils-$version \
bzr+ssh://bzr.debian.org/bzr/pkg-samba/cifs-utils/upstream/HEAD
No distribution specified, and no changelog, assuming 'debian'
Committing to: /tmp/tmpbzOVMs/upstream/
Committed revision 2.
All changes applied successfully.
The new upstream version has been imported.
You should now review the changes and then commit.
$ bzr diff
<review changes>
$ bzr commit -m "merge upstream $version"
Committing to: bzr+ssh://bzr.debian.org/bzr/pkg-samba/cifs-utils/trunk
modified debian/changelog
Committed revision 50.
$
And that's it! It's exciting to see signs of real interoperability between
DVCSes at last. Thanks to everyone who's helped make it possible!